Frappe 프레임워크 안내서

Frappe 프레임워크 안내서

1. Frappe 프레임워크 개론

1.1 탄생과 철학: 시맨틱 웹에서 ’Batteries Included’까지

Frappe 프레임워크의 개발 여정은 2005년, 정보의 표현 방식(예: 제목, 본문)뿐만 아니라 그 의미(예: 이름, 주소)까지 기술하는 프레임워크를 지향했던 시맨틱 웹(Semantic Web) 개념에서 영감을 받아 시작되었다.1 이 초기 비전은 메타데이터의 손쉬운 정의를 통해 복잡한 애플리케이션 구축을 용이하게 만드는 것이었다. 시맨틱에 기반을 둔 애플리케이션은 사용자의 상호작용 방식에 초점을 맞춘 시스템보다 훨씬 더 일관성 있고 확장 가능한 구조를 갖게 된다.1

이 프레임워크는 이론적 배경 속에서만 발전한 것이 아니다. 오히려 700개 이상의 객체 유형을 가진 거대한 애플리케이션인 ERPNext를 구동하기 위한 실질적인 필요에 의해 탄생하고 진화했다.1 Frappe의 핵심 기능들은 이 대규모 전사적 자원 관리(ERP) 시스템을 구축하고 유지보수하는 과정에서 발생한 현실적인 요구사항을 해결하기 위해 개발되었다.4 이러한 ‘애플리케이션 우선’ 개발 방식은 Frappe 프레임워크의 가장 중요한 특징 중 하나인 ‘Batteries Included’ 철학으로 직접 이어진다. 범용 프레임워크가 추상적인 기능 집합을 제공하는 것과 달리, Frappe의 기능들은 실제 복잡한 엔터프라이즈 애플리케이션의 요구에 의해 검증된 것들이다. 이는 프레임워크가 특정 목적(데이터베이스 기반 비즈니스 애플리케이션)에 대해 매우 독자적인(opinionated) 구조를 갖게 하지만, 동시에 해당 영역에서는 매우 실용적이고 강력한 도구가 되게 하는 이유이다.

Frappe의 핵심 개발 철학은 ’코드를 통한 구현보다 설정을 통한 구성(Configuration over Code)’으로 요약할 수 있으며, 가능한 한 적은 코드를 작성하는 것을 목표로 한다.3 만약 어떤 기능이 일반적이고 필요하다고 판단되면, 그 기능은 프레임워크의 핵심부에 직접 통합된다. 이 철학은 Frappe의 신속한 애플리케이션 개발(Rapid Application Development, RAD) 역량의 근간을 이룬다.6

’Batteries Included’라는 용어는 Python의 철학에서 차용한 것으로 7, Frappe가 풀스택 프레임워크로서 현대적인 웹 애플리케이션에 필요한 거의 모든 도구를 기본적으로 제공함을 의미한다.8 여기에는 메타데이터 기반의 ORM, REST API 자동 생성, 사용자 및 역할 기반 권한 관리, PDF 생성, 이메일 및 SMS 연동, 백그라운드 작업 처리, 그리고 강력한 내장 관리자 UI(‘데스크’) 등이 포함된다.2 이 접근법은 개발자가 반복적인 상용구 코드(boilerplate) 작성이나 여러 서드파티 구성요소의 통합에 시간을 낭비하는 대신, 비즈니스 로직 자체에 집중할 수 있도록 한다.2

더 나아가, Frappe는 ’진정한 오픈소스(True Open Source)’를 지향한다.11 GPL-3.0-only 라이선스로 배포되며 6, 이는 핵심 기능들을 독점적인 확장 기능 뒤에 숨기는 ‘오픈코어(open-core)’ 비즈니스 모델과 의도적으로 차별화되는 지점이다. 이러한 결정은 특정 벤더에 대한 종속성을 없애고 커뮤니티 주도의 혁신을 장려한다.2 이 모델을 완전히 수용하기까지의 과정에서 2011년 Google Code에서 GitHub로 이전한 것은 커뮤니티 참여를 활성화하는 중요한 전환점이 되었다.4 이처럼 진정한 오픈소스 모델에 대한 헌신은 단기적인 수익을 일부 희생할 수 있지만, 장기적으로는 커뮤니티의 신뢰를 구축하고 강력한 서드파티 앱 및 서비스 제공자 생태계를 조성한다. 이는 플랫폼의 지속 가능성을 보장하며, 기업이 장기적인 관점에서 Frappe를 기술 스택으로 채택할 때 더 신뢰할 수 있는 선택지가 되게 한다.

1.2 메타데이터 기반 아키케처의 이해

Frappe 프레임워크의 가장 핵심적인 차별점은 메타데이터(meta-data)를 코드나 설정 파일이 아닌 데이터 그 자체로 취급한다는 점이다.5 애플리케이션의 모델, 폼, 그리고 다양한 기능들을 정의하는 이 메타데이터는 ’DocType’이라는 특별한 모델을 통해 데이터베이스 내에 직접 저장된다.13

메타데이터가 데이터베이스에 저장되기 때문에, 프레임워크는 코드 변경이나 재배포 과정 없이 실시간으로 데이터베이스 테이블을 생성하고, 사용자 인터페이스(UI) 폼을 렌더링하며, 애플리케이션의 동작을 구성할 수 있다.5 이 동적 생성 메커니즘이야말로 Frappe가 제공하는 로우코드(low-code) 및 신속한 애플리케이션 개발(RAD) 능력의 핵심이다.2

Frappe는 의도적으로 모놀리식(monolithic) 아키텍처를 채택하여, 개발과 배포 과정을 단순화하는 통합된 환경을 제공한다.9 그러나 이 모놀리식 구조는 매우 높은 확장성을 갖도록 설계되었다. 모듈화된 ‘앱(App)’ 시스템과 강력한 ‘훅(Hooks)’ 시스템을 통해 개발자는 핵심 코드베이스를 직접 수정하지 않고도 새로운 기능을 추가하거나 기존 기능을 변경할 수 있다.2

1.3 ERPNext와 생태계

ERPNext는 Frappe 프레임워크 위에서 구축된 최초이자 가장 포괄적인 애플리케이션이다. 회계, CRM, 제조, 인사 관리 등 다양한 비즈니스 모듈을 포함하는 완전한 오픈소스 ERP 솔루션이다.6 ERPNext는 프레임워크의 발전을 이끄는 주요 동력이자 실세계의 시험장 역할을 한다. 반대로 프레임워크는 ERPNext와 같이 복잡한 애플리케이션을 상대적으로 작은 개발팀이 효율적으로 개발하고 유지보수할 수 있도록 안정적이고 풍부한 기능의 기반을 제공한다.3

Frappe 생태계는 ERPNext를 넘어 확장되고 있다. Frappe Technologies와 커뮤니티는 프레임워크를 기반으로 Frappe HR, Frappe Health, Frappe CRM, Insights 등 다양한 애플리케이션을 개발해왔다.18 이 생태계는 전 세계 20,000명 이상의 개발자와 사용자로 구성된 거대한 커뮤니티에 의해 뒷받침된다.2 커뮤니티의 기여물은 FrappeCloud Marketplace를 통해 공유되며, 이곳에서는 서드파티 통합, 지역화, 특정 산업 솔루션 등을 위한 앱들을 찾을 수 있다.20

Frappe의 비즈니스 모델은 Frappe Cloud를 통한 관리형 호스팅 서비스와 Frappe Technologies 및 전 세계 200개 이상의 인증 파트너 네트워크가 제공하는 엔터프라이즈 지원 및 보증 서비스에 기반을 두고 있다.1

2. 핵심 아키텍처 분석

2.1 풀스택 구조와 기술 스택

Frappe는 백엔드(Python)와 프론트엔드(JavaScript, Vue, SCSS, HTML) 개발을 단일 통합 플랫폼에서 모두 처리하는 풀스택(full-stack) 프레임워크이다.1

백엔드 구성 요소:

  • Python: 서버 사이드 비즈니스 로직을 위한 주 언어이다.1

  • MariaDB: 데이터 저장을 위한 기본 데이터베이스이며, PostgreSQL도 베타 버전으로 지원된다.5

  • Redis: 캐싱, 백그라운드 작업 큐(Python RQ 기반), 그리고 socket.io를 통한 실시간 발행/구독(pub/sub) 이벤트 처리에 사용된다.5

프론트엔드 구성 요소:

  • 프론트엔드는 단일 페이지 애플리케이션(Single-Page Application, SPA) 구조를 가진다.5

  • 전통적으로 JavaScript(jQuery)와 Bootstrap을 기반으로 구축되었으나 5, 최근에는 현대적인 사용자 경험을 제공하기 위해 Frappe UI라는 Vue 기반의 UI 라이브러리를 점차 도입하고 있다.1

전체 아키텍처는 모델-뷰-컨트롤러(Model-View-Controller, MVC) 패턴을 중심으로 설계되어 명확한 관심사 분리를 보장한다.8 여기서 DocType은 모델과 뷰의 정의를 통합하는 역할을 하며, Python 컨트롤러 클래스가 비즈니스 로직을 처리한다.25

2.2 Bench: 개발 및 배포 관리 도구

Bench는 전체 Frappe 스택을 관리하기 위한 통합 명령줄 인터페이스(CLI) 도구로, 개발 및 운영 환경 모두에서 필수적인 역할을 수행한다.3 ‘Batteries Included’ 철학은 필연적으로 웹 서버, 데이터베이스, 캐싱, 백그라운드 워커 등 다양한 구성 요소를 포함하게 되는데,

Bench는 이러한 복잡성을 관리하기 위한 통합 도구로서 탄생했다. Bench가 없다면 이 모든 개별 구성 요소들을 설정하고 관리하는 것은 매우 번거롭고 오류 발생 가능성이 높을 것이다. bench init, bench new-site, bench start, bench setup production과 같은 간단한 명령어들은 수십 개의 개별 시스템 설정 단계를 추상화하여, 모놀리식 아키텍처를 실용적으로 관리할 수 있게 만든다.

Benchfrappe-bench라는 격리된 디렉토리 환경을 생성하며, 이 안에는 Python 가상 환경(virtualenv), 앱, 사이트, 설정 파일 등이 포함된다.5 이를 통해 프로젝트 간의 의존성 및 설정 충돌을 방지한다. 개발 환경에서는 bench start 명령어가 Procfile을 사용하여 웹 서버, 워커, 스케줄러 등 필요한 모든 프로세스를 실행한다. 반면, 운영 환경에서는 bench setup production 명령어가 NGINX와 Supervisor 같은 서비스를 설정하여 안정적인 프로세스 관리를 보장한다.3

Bench의 가장 강력한 기능 중 하나는 멀티테넌시(multi-tenancy) 지원이다. 단일 frappe-bench 인스턴스(하나의 코드베이스)에서 각각 별도의 데이터베이스와 설정을 가진 여러 개의 ’사이트’를 운영할 수 있다.3 또한, 동일 서버에서 다른 버전의 Frappe 환경을 운영하기 위한 포트 기반 멀티테넌시도 지원한다.3

2.2.1 Bench CLI 주요 명령어

개발자가 Frappe 워크플로에 빠르게 적응할 수 있도록, 다음 표는 가장 일반적으로 사용되는 Bench 명령어들을 요약하여 제공한다.

분류명령어설명
설정bench init [bench-name]격리된 환경을 갖춘 새로운 벤치 디렉토리를 초기화한다.
bench get-app [git-url]Git 저장소에서 apps 폴더로 앱을 다운로드한다.
bench startProcfile을 사용하여 개발 서버를 시작한다.
bench setup production [user]운영 환경을 위해 NGINX, Supervisor 등의 서비스를 설정한다.
사이트 관리bench new-site [site-name]새로운 데이터베이스와 함께 새 사이트를 생성한다.
bench --site [site-name] install-app [app-name]특정 사이트에 앱을 설치한다.
bench --site [site-name] list-apps사이트에 설치된 모든 앱 목록을 보여준다.
bench --site [site-name] mariadb해당 사이트의 데이터베이스에 대한 MariaDB 콘솔을 연다.
앱 관리bench new-app [app-name]기본적인 구조를 갖춘 새로운 Frappe 앱을 생성한다.
bench migrate모든 사이트의 모든 앱에 대해 데이터베이스 스키마 마이그레이션을 실행한다.
bench update모든 앱의 업데이트를 가져오고 마이그레이션을 실행한다.
프로세스 제어bench restart모든 벤치 프로세스(웹, 워커, 스케줄러)를 재시작한다.
bench enable-scheduler사이트의 백그라운드 작업 스케줄러를 활성화한다.

2.3 사이트, 앱, 모듈의 계층 구조

Frappe 아키텍처는 명확한 계층 구조를 가진다.

  • Bench: 전체 환경을 관리하는 최상위 컨테이너이다.8

  • Site: 자체 데이터베이스, 설정 파일(site_config.json), 그리고 공개/비공개 파일을 가진 애플리케이션의 특정 인스턴스이다. 하나의 벤치는 여러 사이트를 호스팅할 수 있다.15

  • App: 특정 기능 집합을 제공하는 모듈의 모음이다. Frappe 자체도 하나의 앱이며, ERPNext나 사용자 정의 library_management 앱과 같이 새로운 기능을 구축할 때 앱을 생성한다.3 앱은 frappe-bench/apps 디렉토리에 저장된다.

  • Module: 앱 내에서 관련된 DocType들을 논리적으로 그룹화한 것이다. 예를 들어, ERPNext의 “Accounts“나 “Stock“이 모듈에 해당한다.15

  • DocType: 모듈 내에서 단일 데이터 엔티티(모델/뷰)를 나타내는 가장 기본적인 구성 요소이다.15

3. DocType 시스템 심층 탐구

3.1 DocType의 개념: 모델과 뷰의 통합

DocType은 Frappe 애플리케이션의 가장 핵심적인 구성 요소이다. 이는 단순한 데이터베이스 테이블이나 모델을 넘어, 데이터 스키마, 비즈니스 로직, 그리고 뷰 렌더링 정보까지 포함하는 포괄적인 정의이다.8

DocType 정의는 tab 접두사가 붙은 데이터베이스 테이블(예: tabToDo)을 자동으로 생성하며, 원시 SQL을 추상화하는 강력한 ORM(Object-Relational Mapping) 계층을 제공하여 CRUD(Create, Read, Update, Delete) 작업을 용이하게 한다.5

하나의 DocType JSON 정의로부터 프레임워크는 관리자 UI인 ’데스크(Desk)’에서 여러 표준 UI 뷰를 자동으로 생성한다.

  • List View: 레코드 목록을 탐색, 필터링, 정렬하기 위한 뷰.5

  • Form View: 개별 레코드를 생성하고 편집하기 위한 뷰로, 파일 첨부, 댓글 등의 기능을 지원한다.5

  • Report View: 리포트 빌더를 통해 생성되는 기본적인 보고서 뷰.13

  • 이 외에도 Kanban, Calendar, Tree 뷰 등을 설정할 수 있다.2

DocType의 정의는 그 자체로 DocType이라는 이름의 DocType 문서로 저장된다. 이러한 자기 참조적 특성(A DocType is also a DocType)은 시스템이 UI를 통해 매우 동적이고 유연하게 커스터마이징될 수 있게 하는 핵심 원리이다.14

3.2 DocType 유형별 분석 및 활용 사례

Frappe는 데이터 모델링의 다양한 요구사항을 충족시키기 위해 여러 유형의 DocType을 제공한다. 각 유형의 특성과 적절한 사용 사례를 이해하는 것은 효과적인 Frappe 애플리케이션을 설계하는 데 있어 매우 중요하다. 다음 표는 각 DocType 유형의 핵심적인 특징을 비교 분석한 것이다.

3.2.1 DocType 유형 비교

유형 (Type)카디널리티 (Cardinality)데이터베이스 표현 (DB Representation)주요 활용 사례 (Primary Use Case)핵심 속성 (Key Property)
StandardOne-to-Many (Multiple records)tab 테이블 생성 (Creates tab table)고객, 제품, 판매 주문 등 일반적인 데이터 모델 (General data models like Customer, Item, Sales Order)(Default)
SingleOne-to-One (Single record)tabSingles 테이블에 키-값으로 저장 (Stored as key-value pairs in tabSingles table)시스템 설정, 전역 구성 등 유일한 값을 가지는 데이터 (Singleton data like System Settings, global configurations)Is Single
ChildMany-to-One (Parent record에 종속)부모 DocType의 일부로 저장됨 (Stored as part of the parent DocType)판매 주문 항목, 주소록 등 부모 문서 내의 표 데이터 (Table data within a parent document, like Sales Order Items, Addresses)Is Child Table
SubmittableOne-to-Many (Lifecycle states)tab 테이블 생성, docstatus 컬럼 추가 (Creates tab table, adds docstatus column)송장, 휴가 신청 등 승인 워크플로가 필요한 문서 (Documents requiring an approval workflow like Invoices, Leave Applications)Is Submittable
TreeHierarchical (Parent-child relationship)tab 테이블 생성, lft, rgt 컬럼 추가 (Creates tab table, adds lft, rgt columns for nesting)계정 과목, 부서, 지역 등 계층 구조 데이터 (Hierarchical data like Chart of Accounts, Departments, Territories)Is Tree
VirtualN/A데이터베이스 테이블을 생성하지 않음 (Does not create a database table)외부 API, 파일, 다른 데이터베이스 등 외부 데이터 소스를 모델링 (Modeling external data sources like APIs, files, or other databases)Virtual DocType

4. Frappe 애플리케이션 개발 워크플로

4.1 개발 환경 구축 및 앱 생성

Frappe 애플리케이션 개발을 시작하기 위해서는 Python, JavaScript, MariaDB/Postgres, HTML/CSS, 그리고 Git에 대한 기본적인 이해가 필요하다.22 개발 환경은 표준 설치 스크립트, 사전 빌드된 VirtualBox VM 이미지, 또는 Docker를 사용하여 구성할 수 있다.30

개발 과정의 첫 단계는 bench init [bench-name] 명령어를 사용하여 새로운 벤치 디렉토리를 초기화하는 것이다.22 그 다음, bench new-app [app-name] 명령어로 새로운 앱을 생성한다. 이 명령어는 hooks.py, modules.txt, 그리고 템플릿 및 공개 자산을 위한 폴더들을 포함하는 표준 디렉토리 구조를 자동으로 생성해준다.15 마지막으로, bench new-site [site-name]를 통해 개발용 사이트를 생성하고, bench --site [site-name] install-app [app-name] 명령어로 해당 사이트에 방금 생성한 커스텀 앱을 설치한다.1

4.2 서버 사이드 개발 (Python)

비즈니스 로직은 DocType과 연관된 Python 컨트롤러 클래스(예: library_member.py) 내에 구현된다. ’컨트롤러 훅(Controller Hooks)’이라고도 불리는 이 메소드들은 문서의 생명주기 동안 특정 시점에 실행된다.14 예를 들어, before_save는 문서가 저장되기 직전에 데이터 조작을 위해 사용되고, validate는 사용자 정의 유효성 검사 로직을 위해, on_submit은 문서가 공식적으로 제출된 후의 작업을 위해 사용된다.

더 간단한 로직이나 파일 시스템 접근 권한이 없는 환경(예: Frappe Cloud)을 위해, UI를 통해 ’서버 스크립트(Server Scripts)’를 생성할 수 있다. 이는 문서 이벤트나 API 호출 시 실행되는 Python 스크립트이지만, 보안을 위해 제한된 환경에서 실행된다.34

Frappe는 데이터 조회를 위한 간결하고 강력한 데이터베이스 API를 제공한다.

  • frappe.db.get_list() / frappe.db.get_all(): 레코드 목록을 조회한다 (권한 확인 여부에 따라 구분됨).

  • frappe.db.get_value(): 단일 필드 값을 조회한다.

  • frappe.db.sql(): ORM으로 표현하기 어려운 경우, 읽기 전용의 원시 SQL 쿼리를 실행한다.25

  • frappe.get_doc() / frappe.new_doc(): 전체 문서 객체를 생성하거나 조회하는 주된 ORM 메소드이다.5

4.3 클라이언트 사이드 개발 (JavaScript)

클라이언트 사이드 로직은 JavaScript를 사용하여 폼에 추가된다. 이 스크립트들은 표준 DocType의 경우 {doctype}.js 파일에 작성되거나, UI를 통해 ’클라이언트 스크립트(Client Script)’로 생성될 수 있다.37

frappe.ui.form.on() 메소드는 폼 이벤트를 처리하는 함수를 바인딩하는 데 사용된다.

  • 문서 이벤트: onload, refresh, validate, before_save, after_save 등.

  • 필드 이벤트: 특정 필드의 값이 변경될 때 트리거된다 (예: item_code(frm) {... }).

  • 자식 테이블 이벤트: fieldname_add, fieldname_remove 등 자식 테이블의 행 추가/삭제 시 트리거된다.38

모든 이벤트 핸들러에는 현재 폼 객체인 frm이 전달되며, 이 객체는 폼을 조작하기 위한 풍부한 API를 제공한다.

  • frm.set_value(): 필드 값을 변경한다.

  • frm.refresh_field(): 필드의 표시를 새로 고친다.

  • frm.set_df_property(): 필드의 속성(예: 읽기 전용, 필수 여부)을 동적으로 변경한다.38

  • frm.set_query(): 링크(Link) 필드에 동적 필터를 적용한다.

  • frm.add_custom_button(): 폼의 툴바에 사용자 정의 버튼을 추가한다.40

서버와의 비동기 통신은 frappe.call을 통해 이루어진다. 이 함수는 @frappe.whitelist() 데코레이터로 지정된 Python 메소드를 호출하여 AJAX 상호작용을 가능하게 한다.42

Frappe는 이처럼 비즈니스 로직을 구현하기 위한 세 가지 뚜렷한 계층을 제공한다: Python 파일 내의 DocType 컨트롤러 메소드, UI에서 정의하는 서버 스크립트, 그리고 JS 파일이나 UI에서 정의하는 클라이언트 스크립트. 이는 명확한 아키텍처 패턴을 반영한다. 컨트롤러 메소드는 모델과 밀접하게 결합된 핵심 비즈니스 로직에, 서버 스크립트는 느슨하게 결합된 확장 기능이나 빠른 프로토타이핑에, 클라이언트 스크립트는 UI/UX 개선 및 클라이언트 측 유효성 검사에 사용된다. 주어진 작업에 적합한 계층을 선택하는 것은 유지보수성이 높은 애플리케이션을 구축하는 데 핵심적인 요소이다. 예를 들어, 복잡한 비즈니스 규칙을 클라이언트 스크립트에 배치하면 API 호출을 통해 우회될 수 있어 데이터 불일치를 유발할 수 있다. 따라서 이러한 계층화된 접근 방식은 강력하지만, 개발자의 신중한 선택을 요구한다.

5. 고급 기능 및 확장성

5.1 Hooks 시스템을 이용한 프레임워크 확장

훅(Hooks)은 소스 코드를 직접 수정하지 않고도 프레임워크 및 앱의 핵심 기능을 확장하거나 재정의(override)하는 기본 메커니즘이다. 훅은 커스텀 앱의 hooks.py 파일에 정의된다.44

  • 문서 이벤트 (doc_events): on_update, after_insert, before_submit 등 모든 문서의 CRUD 생명주기 동안 사용자 정의 Python 코드를 실행할 수 있는 강력한 훅이다. 로깅이나 통합 트리거와 같은 횡단 관심사(cross-cutting concerns)를 추가하는 데 선호되는 방식이다.44

  • 클래스 재정의 (override_doctype_class): DocType의 표준 Python 컨트롤러 클래스를 사용자 정의 클래스로 대체하여 메소드를 확장할 수 있게 한다.44

  • 화이트리스트 메소드 재정의 (override_whitelisted_methods): API로 접근 가능한 핵심 메소드의 로직을 가로채고 대체한다.44

  • 자산 주입 (app_include_js, web_include_css): 사용자 정의 JavaScript 및 CSS 파일을 데스크나 웹사이트 페이지에 주입한다.44

  • 스케줄러 이벤트 (scheduler_events): 주기적인 백그라운드 작업을 정의한다.

5.1.1 주요 문서 생명주기 Hooks

견고한 비즈니스 로직을 올바른 단계에 구현하기 위해서는 서버 사이드 문서 이벤트의 생명주기를 이해하는 것이 필수적이다. 다음 표는 DocType 컨트롤러와 hooks.pydoc_events를 통해 사용할 수 있는 가장 중요한 이벤트들을 요약한 것이다.

훅 / 이벤트트리거 시점일반적인 사용 사례
before_insert새 문서가 처음 저장될 때, DB에 기록되기 전.다른 필드에 의존하는 기본값을 설정한다.
validate매 저장 시 before_save 직전.서버 사이드 로직이 필요한 복잡한 필드 간 유효성 검사를 수행한다.
before_save문서가 저장될 때(신규 또는 기존), DB에 기록되기 전.계산된 값을 읽기 전용 필드에 설정한다(예: full_name).
after_save문서가 DB에 성공적으로 저장된 후.변경 사항을 로깅하거나 동일 트랜잭션에 포함될 필요 없는 작업을 수행한다.
before_submit제출 가능 문서의 상태가 ‘Submitted’(docstatus=1)로 변경되기 전.문서가 불변 상태가 되기 전 최종 유효성 검사를 수행한다.
on_submit제출 가능 문서가 성공적으로 제출된 후.연결된 문서를 생성하거나(예: 판매 주문에서 배송 노트 생성), 외부 API를 호출한다.
before_cancel제출된 문서의 상태가 ‘Cancelled’(docstatus=2)로 변경되기 전.취소를 막아야 하는 조건(예: 결제 완료 여부)을 확인한다.
on_cancel제출된 문서가 성공적으로 취소된 후.회계 전표를 되돌리거나 재고 수준을 업데이트한다.
on_update_after_submit제출된 문서가 업데이트된 후(특정 필드만 허용).변경 사항에 따라 값을 재계산하거나 연결된 문서를 업데이트한다.

5.2 REST API를 활용한 외부 연동

Frappe 프레임워크는 모든 DocType에 대해 표준 CRUD(Create, Read, Update, Delete) 작업을 지원하는 완전한 REST API를 자동으로 생성한다.1

인증 방식:

  • 토큰 기반: API 키와 시크릿 쌍을 사용한다. 서버 간 통합에 권장되는 방식이다.46

  • 비밀번호 기반: 세션 쿠키 인증을 사용하며, 클라이언트 사이드 애플리케이션에 적합하다.46

  • OAuth 2.0: 서드파티 애플리케이션 인증에 사용된다.47

리소스 API 엔드포인트:

  • GET /api/resource/:doctype: 필터링, 정렬, 페이지네이션을 포함한 문서 목록 조회.

  • POST /api/resource/:doctype: 새 문서 생성.

  • GET /api/resource/:doctype/:name: 특정 문서 조회.

  • PUT /api/resource/:doctype/:name: 문서 업데이트.

  • DELETE /api/resource/:doctype/:name: 문서 삭제.

또한, @frappe.whitelist() 데코레이터로 장식된 모든 Python 함수는 /api/method/... 엔드포인트를 통해 API로 호출될 수 있다. 이는 사용자 정의 비즈니스 로직을 외부 시스템에 노출하는 주된 방법이다.25

5.3 백그라운드 작업과 스케줄러

Frappe는 웹 요청의 타임아웃을 방지하기 위해 오래 실행되는 작업을 비동기적으로 처리하는 데 Python RQ(Redis Queue)를 사용한다.8 작업은 frappe.enqueue() 함수를 사용하여 큐에 추가되며, 이 함수는 실행할 메소드와 그 인자들을 전달받는다.48

기본적으로 short, default, long 세 가지 큐가 제공되며, 각각 다른 타임아웃 값을 가진다. 전용 워커(worker)들이 이 큐들로부터 작업을 가져와 처리한다.27 내장된 스케줄러는 주기적인 작업을 실행하며, 이러한 작업들은 hooks.pyscheduler_events 훅에 정의된다.49

hourly, daily, weekly, monthly와 같은 일반적인 이벤트와 함께, 정밀한 스케줄링을 위한 cron 문자열도 지원된다.49 특정 사이트의 스케줄러는 bench --site [site-name] enable-scheduler 명령어로 명시적으로 활성화해야 한다.51

이처럼 통합된 백그라운드 작업 및 스케줄러 시스템은 견고한 엔터프라이즈 애플리케이션을 구축하는 데 있어 매우 중요한 기능이다. 대용량 보고서 생성, 대량 이메일 발송, 서드파티 시스템과의 데이터 동기화와 같은 비즈니스 프로세스는 사용자 대면 요청-응답 주기에서 분리되어야 한다. Frappe가 이러한 패턴을 기본적으로, 사전 구성된 상태로 지원한다는 점은 처음부터 이 기능을 직접 구축하고 통합해야 하는 다른 프레임워크에 비해 상당한 이점을 제공한다. 이는 Frappe가 엔터프라이즈 애플리케이션의 요구사항을 깊이 이해하고 있음을 보여주는 증거이다.

5.4 리포팅 엔진: 리포트 빌더, 쿼리 및 스크립트 리포트

Frappe는 다양한 복잡성과 사용자 기술 수준에 맞춰 세 가지 계층의 보고 시스템을 제공한다.54

  • 리포트 빌더(Report Builder): 코드가 필요 없는 도구로, 단일 DocType에서 간단한 보고서를 생성하는 데 사용된다. 사용자는 UI에서 직접 컬럼 선택, 필터 적용, 정렬 및 그룹화를 수행할 수 있다.55

  • 쿼리 리포트(Query Report): 여러 테이블의 데이터를 조인해야 하는 더 복잡한 보고서를 위해 사용된다. UI에서 직접 SQL 쿼리를 작성하여 생성하며, 동적 필터는 별도의 .js 파일에서 정의할 수 있다.54

  • 스크립트 리포트(Script Report): 복잡한 데이터 처리와 로직이 필요한 경우에 사용되는 가장 강력한 옵션이다. Python(.py 파일)으로 작성되며, 컬럼을 정의하고 Frappe API에 대한 전체 접근 권한을 가지고 데이터를 처리할 수 있다. 프론트엔드 필터는 .js 파일에서 정의된다.54

6. 결론: Frappe 프레임워크의 현재와 미래

6.1 주요 특징 요약 및 권장 사용 사례

Frappe 프레임워크는 메타데이터 기반 아키텍처, ‘Batteries Included’ 철학, 신속한 애플리케이션 개발, 내장된 관리자 UI, 그리고 높은 확장성이라는 핵심적인 강점을 가지고 있다. 이러한 특징들 덕분에 데이터베이스 기반의 비즈니스 애플리케이션, ERP, CRM 등 구조화된 데이터, 복잡한 워크플로, 그리고 역할 기반 권한을 필요로 하는 시스템을 구축하는 데 특히 적합하다.58

그러나 Frappe의 독자적인 구조와 모놀리식 아키텍처는 특정 영역에서는 장점이지만, 마이크로서비스나 다른 기술 스택을 선호하는 애플리케이션에는 덜 적합할 수 있다. 또한, 내장된 기능이 광범위하기 때문에 초기 학습 곡선이 다소 가파를 수 있다.1

6.2 커뮤니티 기반의 지속 가능한 발전

Frappe 프레임워크의 미래는 크고 활동적인 글로벌 커뮤니티에 의해 보장된다. 이 커뮤니티는 개발에 기여하고, 포럼을 통해 지원을 제공하며, 서드파티 앱을 구축하는 등 생태계의 성장에 핵심적인 역할을 한다.2

Frappe Technologies의 비즈니스 모델은 라이선스 판매가 아닌 호스팅 및 엔터프라이즈 서비스에 중점을 두고 있어, 핵심 제품이 무료이며 제약 없이 유지될 수 있도록 하는 오픈소스 정신과 일치한다.17 ERPNext 및 다른 공식 앱들의 지속적인 개발은 프레임워크의 진화를 계속해서 이끌 것이며, 이를 통해 Frappe는 복잡한 실제 비즈니스 과제를 해결할 수 있는 현대적이고 안전하며 강력한 플랫폼으로 남을 것이다.4 Frappe UI에서 Vue.js와 같은 현대적인 프론트엔드 기술을 채택하는 것은 플랫폼을 최신 상태로 유지하려는 의지를 보여준다.16

7. 참고 자료

  1. frappe/frappe: Low code web framework for real world applications, in Python and Javascript, https://github.com/frappe/frappe
  2. Web Development Framework - Frappe, https://frappe.io/framework
  3. Why Frappe Framework? - Documentation for Frappe Apps, https://docs.frappe.io/framework/user/en/basics/why
  4. The ERPNext Story - Frappe, https://frappe.io/story
  5. Frappe Framework Tutorial | PDF - Scribd, https://www.scribd.com/document/677710773/Frappe-Framework-Tutorial
  6. ERPNext - Wikipedia, https://en.wikipedia.org/wiki/ERPNext
  7. “batteries included” philosophy, is a good practice? - Python - Reddit, https://www.reddit.com/r/Python/comments/2tzfbv/batteries_included_philosophy_is_a_good_practice/
  8. Frappe Mastery-Introduction-Part 1 | by Sarath Kumar R S | Sep, 2025 - Medium, https://sarathkumarrs.medium.com/frappe-mastery-introduction-part-1-5dec800133ab
  9. An Introduction to Frappe Framework: Features and Benefits - Simple Talk, https://www.red-gate.com/simple-talk/development/web/an-introduction-to-frappe-framework-features-and-benefits/
  10. Frappe Framework Documentation | PDF | File Format - Scribd, https://www.scribd.com/document/426564770/Frappe-Framework-Documentation
  11. True Open Source, True Freedom: The Frappe Framework Story - FOSS United, https://fossunited.org/c/coimbatore/2025/sept/cfp/07jv3caf4m
  12. Introduction - Documentation for Frappe Apps, https://docs.frappe.io/framework/user/en/introduction
  13. What is Frappe Framework?, https://docs.frappe.io/framework/user/en/basics
  14. Understanding DocTypes - Documentation for Frappe Apps, https://docs.frappe.io/framework/user/en/basics/doctypes
  15. How does the Frappe Framework work? - gavin’s Space, https://gavv.in/blog/how-does-the-frappe-framework-work/
  16. frappe/erpnext: Free and Open Source Enterprise Resource Planning (ERP) - GitHub, https://github.com/frappe/erpnext
  17. Why Frappe Services business white paper, https://erpnext.com/whitepapers/why-frappe-services
  18. Frappe Health, https://frappehealth.com/docs
  19. Frappe: Open Source Software, https://frappe.io/
  20. Frappe Ecosystem, https://frappe.io/partner/frappe-ecosystem
  21. ERPNext United States | Open Source ERP - Frappe, https://frappe.io/erpnext/usa
  22. A complete Guide on Frappe Framework - Advantages, Key Features - Techify Solutions, https://techifysolutions.com/blog/frappe-framework/
  23. Frappe Framework Tutorial - Documentation for Frappe Apps, https://docs.frappe.io/framework/user/en/tutorial
  24. Frappe: Benefits, Purpose, Terminologies and Key Concepts | by MICHAEL MAMMAN, https://medium.com/@michaelyak66/frappe-benefits-purpose-terminologies-and-key-concepts-589491fa2b74
  25. Understanding Frappe Framework: Core Concepts and Learning …, https://www.reddit.com/r/django/comments/1i9rtcr/understanding_frappe_framework_core_concepts_and/
  26. Architecture - Documentation for Frappe Apps, https://docs.frappe.io/framework/user/en/basics/architecture
  27. Adding RQ Worker in Frappe: Development vs Production Environments | by Prasant Pant | Aug, 2025 | Medium, https://medium.com/@prasantpant/understanding-rq-worker-in-frappe-development-vs-production-environments-61b5abafe666
  28. Understanding DocTypes | Frappe Content licensed CC-BY-SA 3.0 - OneHash, https://help.onehash.ai/en/article/understanding-doctypes-jk5vbt/
  29. Getting started with Frappe framework - A beginner’s guide - Hybrowlabs Technologies, https://hybrowlabs.com/blog/getting-started-with-frappe-framework-a-beginners-guide
  30. Basic coding guide for Frappe - ERPNext: Part 1 | by Alain Berger - Medium, https://medium.com/frapp%C3%A9-thoughts/basic-guide-to-coding-on-frappe-7bf230195426
  31. How to create custom app (hello world) in Frappe ERPNext, https://discuss.frappe.io/t/how-to-create-custom-app-hello-world-in-frappe-erpnext/123015
  32. Create an App - Documentation for Frappe Apps, https://docs.frappe.io/framework/user/en/tutorial/create-an-app
  33. Controller Methods - Documentation for Frappe Apps, https://docs.frappe.io/framework/user/en/tutorial/controller-methods
  34. Server Scripts in Frappe HR: Using SQL Queries in Python to Fetch and Utilize Data | by Aalam Info Solutions LLP | Medium, https://medium.com/@aalam-info-solutions-llp/server-scripts-in-frappe-hr-using-sql-queries-in-python-to-fetch-and-utilize-data-9a0490599966
  35. Server Script - Documentation for Frappe Apps, https://docs.frappe.io/framework/user/en/desk/scripting/server-script
  36. Server Script - ERPNext Documentation, https://multisaber.angolaerp.co.ao/docs/user/manual/en/customize-erpnext/server-script
  37. Client Script - Documentation for Frappe Apps, https://docs.frappe.io/framework/user/en/desk/scripting/client-script
  38. Client side scripting · frappe/frappe Wiki - GitHub, https://github.com/frappe/frappe/wiki/Client-side-scripting
  39. Developer Cheatsheet · frappe/frappe Wiki - GitHub, https://github.com/frappe/frappe/wiki/Developer-Cheatsheet
  40. Custom Buttons - Client Scripts in Frappe Framework and ERPNext - YouTube, https://www.youtube.com/watch?v=Y4WyZgHeW4Q
  41. Client Script, Server Script, System Console - examples and walthroughs for beginners, https://cloud.erpgulf.com/blog/blogs/client-script-server-script-system-console-examples-and-walthroughs-for-beginners
  42. Server Script - Frappe Tutorial, https://sanskar.frappe.cloud/lms/courses/frappe-tutorial/learn/2-32
  43. Frappe ERPNext Client Script, Server Script, System Console - examples & walkthroughs for beginners : r/ERPGulf - Reddit, https://www.reddit.com/r/ERPGulf/comments/1403os1/frappe_erpnext_client_script_server_script_system/
  44. Hooks - Documentation for Frappe Apps, https://docs.frappe.io/framework/user/en/python-api/hooks
  45. Document Event Hooks in Frappe - Aakvatech, https://support.aakvatech.com/wiki/document-event-hooks-in-frappe
  46. REST API - Documentation for Frappe Apps, https://docs.frappe.io/framework/user/en/api/rest
  47. alyf-de/frappe_api-docs: Unofficial documentation of the Frappe / ERPNext API - GitHub, https://github.com/alyf-de/frappe_api-docs
  48. Running Background Jobs - Documentation for Frappe Apps, https://docs.frappe.io/framework/user/en/guides/app-development/running-background-jobs
  49. Background Jobs - Documentation for Frappe Apps, https://docs.frappe.io/framework/user/en/api/background_jobs
  50. Background jobs - Frappe training session - ERPGulf, https://cloud.erpgulf.com/blog/blogs/background-jobs-frappe-training-session
  51. Why Frappe Framework Scheduler Task never runs? | by Abdullah Abouzekry - Medium, https://medium.com/@abouzekry/why-frappe-framework-scheduler-task-never-runs-51e20bc93f77
  52. How to create scheduled cron job/background task? - Customization - Frappe Forum, https://discuss.frappe.io/t/how-to-create-scheduled-cron-job-background-task/80835
  53. Scheduling Issue: Task Incompletion by Scheduler - Frappe …, https://discuss.frappe.io/t/scheduling-issue-task-incompletion-by-scheduler/122068
  54. Making Custom Reports - Documentation for Frappe Apps, https://docs.frappe.io/erpnext/user/manual/en/making-custom-reports
  55. Report Builder - Documentation for Frappe Apps, https://docs.frappe.io/framework/user/en/desk/reports/report-builder
  56. 21.2 Type of Reporting - erpnext_admin_guide | ERPNext Administrators Guide, https://jwrober.github.io/erpnext_admin_guide/reporting/types.html
  57. How To Create Custom Report in Frappe? | PDF - Scribd, https://www.scribd.com/document/866804744/How-to-Create-Custom-Report-in-Frappe
  58. My Experience with Frappe Framework: A Developer’s Journey [Long Post] - Reddit, https://www.reddit.com/r/frappe_framework/comments/1ivb1wq/my_experience_with_frappe_framework_a_developers/